package com.example.dingding.config;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.aliyun.dingtalkoauth2_1_0.models.CreateJsapiTicketResponse;
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenRequest;
import com.aliyun.dingtalkoauth2_1_0.models.GetAccessTokenResponse;
import com.aliyun.tea.TeaException;
import com.aliyun.teaopenapi.models.Config;
import com.aliyun.teautil.models.RuntimeOptions;
import com.dingtalk.api.DefaultDingTalkClient;
import com.dingtalk.api.DingTalkClient;
import com.dingtalk.api.request.OapiV2UserGetRequest;
import com.dingtalk.api.response.OapiV2UserGetResponse;
import com.example.dingding.constants.RedisConstants;
import com.example.dingding.util.RedisCache;
import com.example.dingding.util.Sample;
import com.taobao.api.ApiException;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.NameValuePair;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;
import org.springframework.util.ObjectUtils;

import javax.servlet.http.HttpServletRequest;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.concurrent.TimeUnit;

@Slf4j
@Component
@Data
public class HttpHelper {

    public static com.aliyun.dingtalkoauth2_1_0.Client createClient() throws Exception {
        com.aliyun.teaopenapi.models.Config config = new com.aliyun.teaopenapi.models.Config();
        config.protocol = "https";
        config.regionId = "central";
        return new com.aliyun.dingtalkoauth2_1_0.Client(config);
    }

    @Value("${useCar.corpid}")
    private String corpid;

    @Value("${useCar.appsecret}")
    private String appsecret;

    @Value("${useCar.agentid}")
    private String agentid;

    @Value("${useCar.appkey}")
    private String appkey;

    @Autowired
    private RedisCache redisCache;

    public static JSONObject httpGet(String url) {
        //创建httpClient
        CloseableHttpClient httpClient = HttpClients.createDefault();
        HttpGet httpGet = new HttpGet(url);                             //生成一个请求
        RequestConfig requestConfig = RequestConfig.custom().         //配置请求的一些属性
                setSocketTimeout(2000).setConnectTimeout(2000).build();
        httpGet.setConfig(requestConfig);                             //为请求设置属性
        CloseableHttpResponse response = null;
        try {
            response = httpClient.execute(httpGet);
            //如果返回结果的code不等于200，说明出错了
            if (response.getStatusLine().getStatusCode() != 200) {
                return null;
            }
            HttpEntity entity = response.getEntity();                 //reponse返回的数据在entity中
            if (entity != null) {
                String resultStr = EntityUtils.toString(entity, "utf-8");//将数据转化为string格式
                JSONObject result = JSONObject.parseObject(resultStr);  //将结果转化为json格式
                if (result.getInteger("errcode") == 0) {                  //如果返回值得errcode值为0，则成功
                    //移除一些没用的元素
                    result.remove("errcode");
                    result.remove("errmsg");
                    return result;                                    //返回有用的信息
                } else {                                                 //返回结果出错了，则打印出来
                    int errCode = result.getInteger("errcode");
                    String errMsg = result.getString("errmsg");
                    throw new Exception("ErrorCode:" + errCode + "ErrorMsg" + errMsg);
                }
            }
        } catch (ClientProtocolException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            if (response != null) try {
                response.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        return null;
    }

    // 调用httpGet方法获得access_token的代码实现：
    public String getAccess_Token() {
        String url = "https://oapi.dingtalk.com/gettoken?" + "appkey=" + appkey + "&appsecret=" + appsecret;
        String cacheObject = (String) redisCache.getCacheObject(RedisConstants.REDIS_USERCAR_ACCESSTOKEN);
        if (!ObjectUtils.isEmpty(cacheObject)) {
            return cacheObject;
        }
        JSONObject res = HttpHelper.httpGet(url);                      //将httpGet方法封装在HttpHelper类中
        String access_token = "";
        if (res != null) {
            access_token = res.getString("access_token");
        } else {
            new Exception("获取token异常");
        }
        //存入Redis缓存
        redisCache.setCacheObject(RedisConstants.REDIS_USERCAR_ACCESSTOKEN, access_token, 7200, TimeUnit.SECONDS);
        return access_token;
    }

    //调用jsapiTickets
    public String getJsapiTicket() throws Exception {
        String userCarJsapiTicket = (String) redisCache.getCacheObject(RedisConstants.REDIS_USERCAR_JSAPITICKET);
        if (!ObjectUtils.isEmpty(userCarJsapiTicket)) {
            return userCarJsapiTicket;
        }
        com.aliyun.dingtalkoauth2_1_0.Client client = Sample.createClient();
        com.aliyun.dingtalkoauth2_1_0.models.CreateJsapiTicketHeaders createJsapiTicketHeaders = new com.aliyun.dingtalkoauth2_1_0.models.CreateJsapiTicketHeaders();
        createJsapiTicketHeaders.xAcsDingtalkAccessToken = getAccess_Token();
        try {
            CreateJsapiTicketResponse jsapiTicketWithOptions = client.createJsapiTicketWithOptions(createJsapiTicketHeaders, new RuntimeOptions());
            //存入Redis缓存
            String jsapiTicket = jsapiTicketWithOptions.getBody().getJsapiTicket();
            redisCache.setCacheObject(RedisConstants.REDIS_USERCAR_JSAPITICKET, jsapiTicket, 7200, TimeUnit.SECONDS);
            return jsapiTicket;
        } catch (TeaException err) {
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
            }
        } catch (Exception _err) {
            TeaException err = new TeaException(_err.getMessage(), _err);
            if (!com.aliyun.teautil.Common.empty(err.code) && !com.aliyun.teautil.Common.empty(err.message)) {
                // err 中含有 code 和 message 属性，可帮助开发定位问题
            }
        }
        return "";
    }

    /**
     * 获取用户信息
     * @param userId 用户编号
     * @param accessToken  访问令牌
     * @return
     * @throws Exception
     */
    public OapiV2UserGetResponse getUserInfo(String userId,String accessToken) throws Exception {
        DingTalkClient client = new DefaultDingTalkClient("https://oapi.dingtalk.com/topapi/v2/user/get");
        OapiV2UserGetRequest req = new OapiV2UserGetRequest();
        req.setUserid(userId);
        req.setLanguage("zh_CN");
        OapiV2UserGetResponse rsp = null;
        try {
            rsp = client.execute(req,accessToken );
        } catch (ApiException e) {
            e.printStackTrace();
        }
        return rsp;
    }


    // 执行POST请求（如果免登录成功后不需要推送钉钉消息，则不需要此方法）
    public static String httpPost(String url, Map<String, Object> params, String encoding) throws Exception {
        String result = "";
        // 创建默认的httpClient实例.
        CloseableHttpClient httpclient = HttpClients.createDefault();
        // 创建httppost
        HttpPost httppost = new HttpPost(url);
        //参数
        List<NameValuePair> formparams = new ArrayList<NameValuePair>();
        if (params != null) {
            Set<String> keys = params.keySet();
            for (String key : keys) {
                formparams.add(new BasicNameValuePair(key, params.get(key).toString()));
            }
        }
        UrlEncodedFormEntity uefEntity;
        try {
            uefEntity = new UrlEncodedFormEntity(formparams, encoding);
            httppost.setEntity(uefEntity);
            CloseableHttpResponse response = httpclient.execute(httppost);
            try {
                Header[] headers = response.getAllHeaders();
                for (Header header : headers) {
                    log.debug(header.getName() + "-->" + header.getValue());
                }
                HttpEntity entity = response.getEntity();
                if (entity != null) {
                    result = EntityUtils.toString(entity, encoding);
                }
            } finally {
                response.close();
            }
        } catch (IOException e) {
            throw e;
        } finally {
            // 关闭连接,释放资源
            try {
                httpclient.close();
            } catch (IOException e) {
            }
        }
        return result;
    }

    //获取应用访问凭证获取小程序内部应用的accessToken。
    public void getAccessToken() throws Exception {
        Config config = new Config();
        config.protocol = "https";
        config.regionId = "central";
        com.aliyun.dingtalkoauth2_1_0.Client client = new com.aliyun.dingtalkoauth2_1_0.Client(config);
        GetAccessTokenRequest accessTokenRequest = new GetAccessTokenRequest()
                .setAppKey("dingtzbfdmhhsemnvx3n")
                .setAppSecret("iejqtcB4oA78ym0PGMUdwszpwMcVmE3H4rOD0M2GcrRUkvOvyJ6-d9s3mYUc3yO_");
        GetAccessTokenResponse accessToken = client.getAccessToken(accessTokenRequest);
        System.out.println(JSON.toJSONString(accessToken.getBody()));
    }
}
